<?php

namespace app\datalog;

use app\datalog\ContextFormatter;
use Monolog\Formatter\JsonFormatter;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Monolog\Processor\ProcessIdProcessor;
use Monolog\Processor\UidProcessor;

class DatalogBase
{
    private $logObj;

    // 日志名称
    protected $name = 'log';

    // 数据存放位置
    protected $logPath = 'datalogs';

    // 最大存储多少天日志
    // 如果填写 0 或 1，则采用 StreamHandler ，否则采用 RotatingFileHandler
    protected $maxSaveDay = 180;

    // 数据存放格式 json、line
    protected $formatter = 'json';

    // 日志级别 emergency、alert、critical、error、warning、notice、info、debug
    protected $logLevel = 'debug';

    /**
     * 单例模式
     * @var obj
     */
    private static $_instance = [];

    /**
     * 获取单例实例化对象
     * @return static
     */
    public static function getInstance(...$args)
    {
        $class = static::class;
        if (!isset(self::$_instance[$class])) {
            self::$_instance[$class] = new $class(...$args);
        }
        return self::$_instance[$class];
    }

    public function getPathFile()
    {
        return "{$this->logPath}/data.log";
    }

    public function __construct()
    {
        $log  = new Logger($this->name);
        $file = $this->getPathFile();
        if ($this->maxSaveDay <= 1) {
            $stream_handler = new StreamHandler($file, $this->logLevel);
        } else {
            $stream_handler = new RotatingFileHandler($file, $this->maxSaveDay, $this->logLevel);
        }

        switch ($this->formatter) {
            case "line":
                $stream_handler->setFormatter(new LineFormatter());
                break;
            case "json":
                $stream_handler->setFormatter(new JsonFormatter());
                break;
            case "context":
                $stream_handler->setFormatter(new ContextFormatter());
                break;
        }
        $log->pushHandler($stream_handler);

        $uid_obj = new UidProcessor();
        $log->pushProcessor($uid_obj);

        $pid_obj = new ProcessIdProcessor();
        $log->pushProcessor($pid_obj);

        $this->logObj = $log;
    }

    /**
     * 记录日志
     * @param  array  $params 日志详情
     * @return boolean
     */
    public function log(array $params)
    {
        $this->logObj->info($this->name, $params);

        return true;
    }
}
